package com.yekaile.carsystem.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yekaile.carsystem.common.Constant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Date;
/**
 * @author yekaile
 */
@PropertySource("classpath:config.properties")
@Component
public class JwtUtil {
    /**
     * 过期时间改为从配置文件获取
     */
    private static String accessTokenExpireTime;

    /**
     * JWT认证加密私钥(Base64加密)
     */
    private static String encryptJWTKey;

    @Value("${accessTokenExpireTime}")
    public void setAccessTokenExpireTime(String accessTokenExpireTime) {
        JwtUtil.accessTokenExpireTime = accessTokenExpireTime;
    }

    @Value("${encryptJWTKey}")
    public void setEncryptJWTKey(String encryptJWTKey) {
        JwtUtil.encryptJWTKey = encryptJWTKey;
    }


    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(encryptJWTKey+getClaim(token, Constant.USERNAME));
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        } catch (SignatureVerificationException | TokenExpiredException e) {
            throw e;
        }
    }

    public static String getClaim(String token, String claim) {
        DecodedJWT decode = JWT.decode(token);
        return decode.getClaim(claim).asString();
    }

    public static String sign(String username, String currentTimeMillis) {
        Date date = new Date(System.currentTimeMillis() + Long.parseLong(accessTokenExpireTime) * 1000);
        String secret =encryptJWTKey+username;
        Algorithm algorithm = Algorithm.HMAC256(secret);
        return JWT.create()
                .withClaim(Constant.USERNAME, username)
                //以ms为单位，所以乘1000
                .withClaim(Constant.CURRENT_TIME_MILLIS, currentTimeMillis)
                .withExpiresAt(date)
                .sign(algorithm);
    }
}
